package com.apartment.own.service.impl;

import java.util.*;


import com.apartment.common.core.domain.BaseEntity;
import com.apartment.common.core.domain.entity.SysUser;
import com.apartment.common.utils.DateUtils;

import com.apartment.common.utils.SecurityUtils;
import com.apartment.own.domain.constant.RedisConstants;
import com.apartment.own.domain.enums.SystemNotificationTypeEnum;
import com.apartment.own.request.sys.NotificationMessageDTO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.apartment.own.mapper.OwnSystemNotificationMessageMapper;
import com.apartment.own.domain.OwnSystemNotificationMessage;
import com.apartment.own.service.IOwnSystemNotificationMessageService;

/**
 * 后台消息通知Service业务层处理
 *
 * @author @Dog_E
 * @date 2020-08-28
 */
@Service
public class OwnSystemNotificationMessageServiceImpl extends ServiceImpl<OwnSystemNotificationMessageMapper, OwnSystemNotificationMessage> implements IOwnSystemNotificationMessageService {
    @Autowired
    private OwnSystemNotificationMessageMapper ownSystemNotificationMessageMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询后台消息通知
     *
     * @param id 后台消息通知ID
     * @return 后台消息通知
     */
    @Override
    public OwnSystemNotificationMessage selectOwnSystemNotificationMessageById(Long id) {
        return ownSystemNotificationMessageMapper.selectOwnSystemNotificationMessageById(id);
    }

    /**
     * 查询后台消息通知列表
     *
     * @param ownSystemNotificationMessage 后台消息通知
     * @return 后台消息通知
     */
    @Override
    public List<OwnSystemNotificationMessage> selectOwnSystemNotificationMessageList(OwnSystemNotificationMessage ownSystemNotificationMessage) {
        return ownSystemNotificationMessageMapper.selectOwnSystemNotificationMessageList(ownSystemNotificationMessage);
    }

    /**
     * 新增后台消息通知
     *
     * @param ownSystemNotificationMessage 后台消息通知
     * @return 结果
     */
    @Override
    public int insertOwnSystemNotificationMessage(OwnSystemNotificationMessage ownSystemNotificationMessage) {
        ownSystemNotificationMessage.setCreateTime(DateUtils.getNowDate());
        return ownSystemNotificationMessageMapper.insertOwnSystemNotificationMessage(ownSystemNotificationMessage);
    }

    /**
     * 修改后台消息通知
     *
     * @param ownSystemNotificationMessage 后台消息通知
     * @return 结果
     */
    @Override
    public int updateOwnSystemNotificationMessage(OwnSystemNotificationMessage ownSystemNotificationMessage) {
        ownSystemNotificationMessage.setUpdateTime(DateUtils.getNowDate());
        return ownSystemNotificationMessageMapper.updateOwnSystemNotificationMessage(ownSystemNotificationMessage);
    }

    /**
     * 批量删除后台消息通知
     *
     * @param ids 需要删除的后台消息通知ID
     * @return 结果
     */
    @Override
    public int deleteOwnSystemNotificationMessageByIds(Long[] ids) {
        return ownSystemNotificationMessageMapper.deleteOwnSystemNotificationMessageByIds(ids);
    }

    /**
     * 删除后台消息通知信息
     *
     * @param id 后台消息通知ID
     * @return 结果
     */
    @Override
    public int deleteOwnSystemNotificationMessageById(Long id) {
        return ownSystemNotificationMessageMapper.deleteOwnSystemNotificationMessageById(id);
    }


    /**
     * @param messageDTO: 查询消息通知DTO
     * @Description: 查询后台消息通知
     * @return: java.util.List<com.apartment.own.domain.OwnSystemNotificationMessage>
     * @Author: @Dog_E
     * @Date: 2020/9/5 0005 11:38
     **/
    @Override
    public List<OwnSystemNotificationMessage> selectMessageList(NotificationMessageDTO messageDTO, SysUser user) {

        Set readIds = null;
        //判断key是否存在  不存在查询会报错
        if (redisTemplate.hasKey(RedisConstants.SystemInformation.USER_HAS_READ + user.getUserId())) {
            //拿到当前用户已读 过得id
            readIds = redisTemplate.opsForSet().members(
                    RedisConstants.SystemInformation.USER_HAS_READ + user.getUserId());
        }
        List<OwnSystemNotificationMessage> messages;
        //未读的消息 未读0
        if (messageDTO.getMessageStatus() == NotificationMessageDTO.UNREAD) {
            messages = ownSystemNotificationMessageMapper.selectList(
                    Wrappers.<OwnSystemNotificationMessage>lambdaQuery()
                            //排除已读  null != readIds如果等于null 则不执行notIn(...)方法
                            .notIn(null != readIds, OwnSystemNotificationMessage::getId, readIds)
                            .eq(OwnSystemNotificationMessage::getMessageType, messageDTO.getMessageType())
                            .orderByDesc(BaseEntity::getCreateTime));
        }
        //已读的消息
        else {
            messages = ownSystemNotificationMessageMapper.selectList(
                    Wrappers.<OwnSystemNotificationMessage>lambdaQuery()
                            //查询已读  null != readIds如果等于null 则不执行in(...)方法
                            .in(null != readIds, OwnSystemNotificationMessage::getId, readIds)
                            .eq(OwnSystemNotificationMessage::getMessageType, messageDTO.getMessageType())
                            .orderByDesc(BaseEntity::getCreateTime));
        }
        return messages;
    }

    /**
     * @param ids:    消息id
     * @param userId: 当前用户id
     * @Description: 增加已读标识
     * @return: 0:失败 1:成功
     * @Author: @Dog_E
     * @Date: 2020/9/5 0005 11:38
     **/
    @Override
    public int increaseTheReadMark(Long[] ids, Long userId) {
        try {
            //批量添加
            for (int i = 0; i < ids.length; i++) {
                redisTemplate.opsForSet().add(RedisConstants.SystemInformation.USER_HAS_READ + userId, ids[i]);
            }
        } catch (Exception e) {
            return 0;
        }
        return 1;
    }

    /**
     * @Description:查询未读条数
     * @return: java.util.Map<java.lang.String, java.lang.Integer>
     * @Author: @Dog_E
     * @Date: 2020/9/8 0008 09:09
     **/
    @Override
    public Map<String, Integer> inquireUnreadNumber() {
        SysUser user = SecurityUtils.getUser();
        Set<Long> readIds = null;
        //判断key是否存在  不存在查询会报错
        if (redisTemplate.hasKey(RedisConstants.SystemInformation.USER_HAS_READ + user.getUserId())) {
            //拿到当前用户已读 过得id
            readIds = redisTemplate.opsForSet().members(
                    RedisConstants.SystemInformation.USER_HAS_READ + user.getUserId());
        }

        //取出所有消息类型  消息条数赋值为0
        Map<String, Integer> map = new HashMap<>();
        for (SystemNotificationTypeEnum notificationType : SystemNotificationTypeEnum.values()) {
            map.put(notificationType.getId().toString(), 0);
        }

        List<Long> ids = new ArrayList<>(readIds);
        //查询未读信息条数
        List<NotificationMessageDTO> typeAndNumber =
                ownSystemNotificationMessageMapper.inquireUnreadNumber(ids);
        typeAndNumber.forEach(type -> {
//            从数据库查询出来的数量进行修改
            map.put(type.getMessageType().toString(),type.getUnreadNumber());
        });
        return map;
    }
}
